package me.out1kiss.www.main;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Main {

    public static void main(String[] args) throws IOException {
        List<Student> students = getStudents(1000000);
//        testObjToJson(students, 100);/getStudents/循环100,每次序列化100W个对象,比较平均时间
        testJsonToObj(students.stream().map(stu -> JSON.toJSON(stu).toString()).collect(Collectors.toList())
                , 100);//循环100,每次反序列化100W个json字符串,比较平均时间
    }

    public static List<Student> getStudents(int count) {
        List<Student> students = new ArrayList<Student>();
        for (int i = 0; i < count; i++) {
            students.add(new Student(
                    RandomUtil.getRandomStr(5),
                    RandomUtil.getRandomLong(),
                    RandomUtil.getRandomInteger()));
        }
        return students;
    }

    //反序列化
    private static void testJsonToObj(List<String> students, int count) throws IOException {
        long fastSumTime = 0L;
        long jacksonSumTime = 0L;
        long fastUseTime = 0L;
        long jacksonUseTime = 0L;
        List<String> compareList = new ArrayList<String>();
        for (int i = 0; i < count; i++) {
            fastUseTime = testFastJsonToObj(students);
            jacksonUseTime = testJacksonJsonToObj(students);
            if (fastUseTime > jacksonUseTime) {
                compareList.add("jackson");
            } else if (fastUseTime < jacksonUseTime) {
                compareList.add("fast");
            } else {
                compareList.add("equal");
            }
            fastSumTime += fastUseTime;
            jacksonSumTime += jacksonUseTime;
        }
        System.out.println(fastSumTime);
        System.out.println(jacksonSumTime);
        System.out.println(Arrays.toString(compareList.toArray()));
    }

    private static long testFastJsonToObj(List<String> students) {
        long fastJsonBegin = System.currentTimeMillis();
        for (String json : students) {
            Student ss = JSON.parseObject(json, new TypeReference<Student>() {
            });
        }
        return System.currentTimeMillis() - fastJsonBegin;
    }

    private static long testJacksonJsonToObj(List<String> students) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        long jacksonBegin = System.currentTimeMillis();
        for (String json : students) {
            objectMapper.readValue(json, Student.class);
        }
        return System.currentTimeMillis() - jacksonBegin;
    }

    //序列化
    private static void testObjToJson(List<Student> students, int count) throws JsonProcessingException {
        long fastSumTime = 0L;
        long jacksonSumTime = 0L;
        long fastUseTime = 0L;
        long jacksonUseTime = 0L;
        List<String> compareList = new ArrayList<String>();
        for (int i = 0; i < count; i++) {
            fastUseTime = testFastObjToJson(students);
            jacksonUseTime = testJacksonObjToJson(students);
            if (fastUseTime > jacksonUseTime) {
                compareList.add("jackson");
            } else if (fastUseTime < jacksonUseTime) {
                compareList.add("fast");
            } else {
                compareList.add("equal");
            }
            fastSumTime += fastUseTime;
            jacksonSumTime += jacksonUseTime;
        }
        System.out.println(fastSumTime);
        System.out.println(jacksonSumTime);
        System.out.println(Arrays.toString(compareList.toArray()));
    }

    /**
     * 对象转json字符串效率对比
     */
    private static long testFastObjToJson(List<Student> students) {
        long fastJsonBegin = System.currentTimeMillis();
        for (Student student : students) {
            JSON.toJSON(student).hashCode();
        }
        return System.currentTimeMillis() - fastJsonBegin;
    }

    /**
     * 对象转json字符串效率对比
     */
    private static long testJacksonObjToJson(List<Student> students) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        long jacksonBegin = System.currentTimeMillis();
        for (Student student : students) {
            objectMapper.writeValueAsString(student).hashCode();
        }
        return System.currentTimeMillis() - jacksonBegin;
    }

    static class Student {

        private String name;
        private Long age;
        private Integer height;

        public Student() {
        }

        public Student(String name, Long age, Integer height) {
            this.name = name;
            this.age = age;
            this.height = height;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Long getAge() {
            return age;
        }

        public void setAge(Long age) {
            this.age = age;
        }

        public Integer getHeight() {
            return height;
        }

        public void setHeight(Integer height) {
            this.height = height;
        }
    }
}
